﻿using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace BToolkit
{
    public class TCPClient
    {
        public event Action<ProtoBase> onReceive;
        public int id;

        private TcpClient client;
        private NetworkStream stream;
        private Thread clientThread;

        public TCPClient()
        {
            MainThreadHelper.Init();
        }

        /// <summary>
        /// callback:连接成功返回客户端id,用于发送消息指明接收对象
        /// </summary>
        public void ConnectToServer(string ipAddress, int port)
        {
            try
            {
                client = new TcpClient();
                client.Connect(ipAddress, port);
                stream = client.GetStream();

                clientThread = new Thread(new ThreadStart(ListenForData));
                clientThread.Start();
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogError($"[TCPClient]连接服务器失败：{ex}");
            }
        }

        private void ListenForData()
        {
            byte[] receivedBuffer = new byte[4096];
            while (true)
            {
                int bytesRead = 0;
                try
                {
                    bytesRead = stream.Read(receivedBuffer, 0, receivedBuffer.Length);
                }
                catch (Exception ex)
                {
                    UnityEngine.Debug.LogError($"[TCPClient]接收服务器消息失败：{ex}");
                    break;
                }
                if (bytesRead == 0)
                {
                    break;
                }

                string msg = Encoding.UTF8.GetString(receivedBuffer, 0, bytesRead);
                //UnityEngine.Debug.Log($"[TCPServer]客户端收到消息：{msg}");
                MainThreadHelper.Run(() =>
                {
                    onReceive?.Invoke(LitJson.JsonMapper.ToObject<ProtoBase>(msg));
                });
            }
        }

        public void Send(ProtoBase protoBase)
        {
            try
            {
                if (stream.CanWrite)
                {
                    string msg = LitJson.JsonMapper.ToJson(protoBase);
                    //UnityEngine.Debug.Log($"[TCPClient]客户端发送消息：{msg}");
                    byte[] data = Encoding.UTF8.GetBytes(msg);
                    stream.Write(data, 0, data.Length);
                }
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogError($"[TCPClient]发送消息失败：{ex}");
            }
        }

        public void Disconnect()
        {
            try
            {
                stream.Close();
                client.Close();
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogError($"[TCPClient]断开连接失败：{ex}");
            }
        }
    }
}